﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace 调平
{
    public class PythonThreadContext : IDisposable
    {
        private readonly bool _enableConsole;
        private Thread _thread;
        private readonly AutoResetEvent _doneEvent = new AutoResetEvent(false);
        private Exception _exception;

        public PythonThreadContext(bool enableConsoleOutput = true)
        {
            _enableConsole = enableConsoleOutput;
        }

        public void Run(Action action)
        {
            _thread = new Thread(() =>
            {
                try
                {
                    if (_enableConsole)
                    {
                        // 重定向控制台输出
                        var originalOut = Console.Out;
                        var writer = new ThreadSafeTextWriter(originalOut);
                        Console.SetOut(writer);

                        action();

                        Console.SetOut(originalOut);
                    }
                    else
                    {
                        action();
                    }
                }
                catch (Exception e)
                {
                    _exception = e;
                }
                finally
                {
                    _doneEvent.Set();
                }
            });

            _thread.SetApartmentState(ApartmentState.STA);
            _thread.Start();

            // 显示进度动画
            while (!_doneEvent.WaitOne(100))
            {
                Console.Write(".");
            }

            if (_exception != null)
            {
                throw new AggregateException("Python线程执行失败", _exception);
            }
        }

        public void Dispose()
        {
            _doneEvent?.Dispose();
        }
    }

    // 线程安全的文本写入器
    public class ThreadSafeTextWriter : TextWriter
    {
        private readonly TextWriter _original;
        private readonly object _lock = new object();

        public ThreadSafeTextWriter(TextWriter original)
        {
            _original = original;
        }

        public override void Write(char value)
        {
            lock (_lock) { _original.Write(value); }
        }

        public override void Write(string value)
        {
            lock (_lock) { _original.Write(value); }
        }

        public override void WriteLine(string value)
        {
            lock (_lock) { _original.WriteLine(value); }
        }

        public override System.Text.Encoding Encoding => _original.Encoding;
    }
}